package com.dm.cloud.utils;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.reflect.MethodUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射调用方法的工具类
 * 为了不破坏封装性 所以不允许调用私有方法
 */
public class ReflectUtils {

    /**
     * 无参无返回值
     * @param classname 类名全路径
     * @param methodName 方法名
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static void execVoidMethod(String classname,String methodName) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //创建类实例
        Class cls = Class.forName(classname);
        Object obj = cls.newInstance();

        Method method = MethodUtils.getMatchingAccessibleMethod(cls, methodName);
        method.setAccessible(true);
        //调用方法
        method.invoke(obj);
    }

    /**
     *
     * @param classname 类名全路径
     * @param methodName 方法名
     * @param params 参数
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static void execVoidMethod(String classname,String methodName,Class[] clss ,Object[] params) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        if(ObjectUtils.isNotEmpty(clss)){
            Class cls = Class.forName(classname);
            Object obj = cls.newInstance();
            Method method = MethodUtils.getMatchingAccessibleMethod(cls, methodName,clss);
            method.setAccessible(true);
            method.invoke(obj, params);
        }else{
            execVoidMethod(classname,methodName);
        }
    }

    /**
     *
     * @param classname 类名全路径
     * @param methodName 方法名
     * @return 返回值
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static Object execRetMethod(String classname,String methodName) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //创建类实例
        Class cls = Class.forName(classname);
        Object obj = cls.newInstance();
        //获取方法
        Method method = MethodUtils.getMatchingAccessibleMethod(cls, methodName);
        method.setAccessible(true);
        //调用方法
        Object result = method.invoke(obj);
        return result;
    }


    /**
     *
     * @param classname 类名全路径
     * @param methodName 方法名
     * @param params 参数
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static Object execRetMethod(String classname,String methodName,Class[] clss ,Object[] params) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        if(ObjectUtils.isNotEmpty(clss)){
            Class cls = Class.forName(classname);
            Object obj = cls.newInstance();
            Method method = MethodUtils.getMatchingAccessibleMethod(cls, methodName,clss);
            method.setAccessible(true);
            Object result = method.invoke(obj, params);
            return result;
        }else{
            return execRetMethod(classname,methodName);
        }
    }
}
